<!-- 蜀海vue组件库page组件 -->
<template>
  <ul class="sh-page" v-if="sizes !== 'small'" :style="styles">
    <div style="display: flex; align-items:center;">
      <div v-if="showSize" :class="selectClass">
        <Select
          v-model="currentPageSize"
          :class="sizeClass"
          :placement="placement"
          @on-change="changeSize"
        >
          <Option
            v-for="item in pageSizeOpts"
            :key="item"
            :value="item"
            :label="item"
            style="text-align:center;"
          >{{item}} {{t('i.page.page')}}</Option>
        </Select>
      </div>
      <span class="sh-page-total" v-if="showTotal">
        <slot>
          {{t('i.page.total')}} {{ total }}
          <template>{{t('i.page.item')}}</template>
        </slot>
      </span>
    </div>
    <div style="display: flex;">
      <li v-if="showText" :class="prevStandTextClass" @click="prev">
        <p>{{t('i.page.prev')}}</p>
      </li>
      <li v-else :class="prevClass" :title="t('i.page.prev')" @click="prev">
        <p>
          <template v-if="prevText !== ''">{{ prevText }}</template>
          <i v-else class="iconfont icon-left-bracket"></i>
        </p>
      </li>
      <li title="1" :class="firstClass" @click="handlePageChange(1)">
        <p>1</p>
      </li>
      <li
        :title="t('i.page.prev5')"
        v-if="showPrewMore"
        :class="[prefixCls + '-item-jump-prev']"
        @click="fastPrev"
      >
        <i class="iconfont icon-right-bracket"></i>
      </li>
      <li
        v-for="pager in pagers"
        :key="pager.id"
        :title="pager.title"
        :class="pager.class"
        @click="handlePageChange(pager.num)"
      >{{pager.num}}</li>
      <li
        :title="t('i.page.next5')"
        v-if="showNextMore"
        :class="[prefixCls + '-item-jump-next']"
        @click="fastNext"
      ></li>
      <li :title="maxPages" v-if="maxPages > 1" :class="lastClass" @click="handlePageChange(maxPages)">
        <p>{{maxPages}}</p>
      </li>
      <li v-if="showText" :class="nextStandTextClass" @click="next">
        <p>{{t('i.page.next')}}</p>
      </li>
      <li v-else :class="nextClass" :title="t('i.page.next')" @click="next">
        <p>
          <template v-if="nextText !== ''">{{ nextText }}</template>
          <i v-else class="iconfont icon-right-bracket"></i>
        </p>
      </li>
      <div v-if="showOpt || showBtu" :class="optionClass">
        <div v-if="showOpt" :class="inputClass">
          {{t('i.page.goto')}}
          <input
            type="text"
            v-model.lazy="showInputValue"
            autocomplete="off"
            spellcheck="false"
            @keyup.enter="keyUpChangePage"
            @input="pageInputChange"
          />
          {{ t('i.page.p') }}
        </div>
        <div v-if="showBtu" class="sh-page-ok-div">
          <Button
            class="sh-page-ok-div-btu"
            :type="showBtuType"
            @click="okBtuChangePage"
          >{{t('i.page.ok')}}</Button>
        </div>
      </div>
    </div>
  </ul>
  <ul v-else class="sh-page-small">
    <div style="display: flex;align-items:center">
      <div v-if="showSize" :class="selectClass">
        <Select
          size="middle"
          v-model="currentPageSize"
          :class="sizeClass"
          :placement="placement"
          @on-change="changeSize"
        >
          <Option
            v-for="item in pageSizeOpts"
            :key="item"
            :value="item"
            :label="item"
            style="text-align:center;"
          >{{item}} {{t('i.page.page')}}</Option>
        </Select>
      </div>
      <span class="sh-page-small-total" v-if="showTotal">
        <slot>
          {{t('i.page.total')}} {{ total }}
          <template>{{t('i.page.item')}}</template>
        </slot>
      </span>
    </div>
    <div style="display: flex;">
      <li v-if="showText && sizes !== 'large'" :class="prevStandTextClass" @click="prev">
        <p>{{t('i.page.prev')}}</p>
      </li>
      <li v-else :class="prevClass" :title="t('i.page.prev')" @click="prev">
        <p>
          <template v-if="prevText !== ''">{{ prevText }}</template>
          <i v-else class="iconfont icon-left-bracket"></i>
        </p>
      </li>
      <li title="1" :class="firstClass" @click="handlePageChange(1)">
        <p>1</p>
      </li>
      <li
        :title="t('i.page.prev5')"
        v-if="showPrewMore"
        :class="[prefixCls + '-item-jump-prev']"
        @click="fastPrev"
      >
        <i class="iconfont icon-right-bracket"></i>
      </li>
      <li
        v-for="pager in pagers"
        :key="pager.id"
        :title="pager.title"
        :class="pager.class"
        @click="handlePageChange(pager.num)"
      >{{pager.num}}</li>
      <li
        :title="t('i.page.next5')"
        v-if="showNextMore"
        :class="[prefixCls + '-item-jump-next']"
        @click="fastNext"
      ></li>
      <li :title="maxPages" v-if="maxPages > 1" :class="lastClass" @click="handlePageChange(maxPages)">
        <p>{{maxPages}}</p>
      </li>
      <li v-if="showText" :class="nextStandTextClass" @click="next">
        <p>{{t('i.page.next')}}</p>
      </li>
      <li v-else :class="nextClass" :title="t('i.page.next')" @click="next">
        <p>
          <template v-if="nextText !== ''">{{ nextText }}</template>
          <i v-else class="iconfont icon-right-bracket"></i>
        </p>
      </li>
      <div v-if="showOpt || showBtu" :class="optionClass">
        <div v-if="showOpt" :class="inputClass">
          {{t('i.page.goto')}}
          <input
            type="text"
            v-model.lazy="showInputValue"
            autocomplete="off"
            spellcheck="false"
            @keyup.enter="keyUpChangePage"
            @input="pageInputChange"
          />
          {{ t('i.page.p') }}
        </div>
        <div v-if="showBtu" class="sh-page-small-ok-div">
          <Button
            size="middle"
            class="sh-page-small-ok-div-btu"
            :type="showBtuType"
            @click="okBtuChangePage"
          >{{t('i.page.ok')}}</Button>
        </div>
      </div>
    </div>
  </ul>
</template>

<script>
import Locale from '../../../mixins/locale'
import Select from '../../select'
import Option from '../../select/src/Option'
import Button from '../../button/src/Button'
import size from '../../../mixins/size'
function isValueNumber (value) {
  return /^[1-9][0-9]*$/.test(value + '')
}
function isPositiveInteger (s) {
  // 是否为正整数
  var re = /^[0-9]+$/
  return re.test(s)
}
export default {
  name: 'Page',
  mixins: [Locale, size],
  components: { Select, Option, Button },
  props: {
    current: {
      type: Number,
      default: 1
    },
    total: {
      type: Number,
      default: 0
    },
    pageSize: {
      type: Number,
      default: 10
    },
    pageSizeOpts: {
      type: Array,
      default () {
        return [10, 20, 30, 50, 100, 200]
      }
    },
    showTotal: {
      type: Boolean,
      default: true
    },
    showSize: {
      type: Boolean,
      default: true
    },
    showOpt: {
      type: Boolean,
      default: true
    },
    showBtu: {
      // 展示确定按钮
      type: Boolean,
      default: true
    },
    showStandardText: {
      // 标准文字
      type: Boolean,
      default: true
    },
    prevText: {
      type: String,
      default: ''
    },
    nextText: {
      type: String,
      default: ''
    },
    disable: {
      type: Boolean,
      default: false
    },
    styles: {
      type: Object
    },
    pagerCount: {
      type: Number,
      validator (value) {
        return (
          (value | 0) === value && value > 4 && value < 22 && value % 2 === 1
        )
      },
      default: 7
    },
    placement: String
  },
  data () {
    return {
      prefixCls: 'sh-page',
      currentPage: this.current,
      currentPageSize: this.pageSize,
      PagerCount: this.pagerCount,
      showPrewMore: false,
      showNextMore: false,
      showInputValue: '',
      showText: this.showStandardText
    }
  },
  computed: {
    pagers () {
      // 计算当前的分页]
      const PagerCount = this.PagerCount
      const pageNum = Number(this.maxPages)
      const currentPage = Number(this.currentPage)
      const halfPagerCount = (PagerCount - 1) / 2
      const array = []
      let showPrewMore = false
      let showNextMore = false
      if (pageNum > PagerCount) {
        if (currentPage > PagerCount - halfPagerCount) {
          showPrewMore = true
        }
      }
      // 最大显示数量为7，所以不能等于7
      if (pageNum !== 7 && pageNum > 6 && (currentPage < pageNum - halfPagerCount)) {
        showNextMore = true
      }
      if (pageNum > 5 && (showNextMore || showPrewMore)) {
        if (showPrewMore && !showNextMore) {
          const startPage = pageNum - (PagerCount - 2)
          for (let i = startPage; i < pageNum; i++) {
            let item = {
              key: i,
              title: i.toString(),
              class: [
                this.prefixCls + '-item',
                {
                  [`${this.prefixCls}-item-active`]: this.currentPage === i
                }
              ],
              num: i
            }
            array.push(item)
          }
        } else if (!showPrewMore && showNextMore) {
          for (let i = 2; i < PagerCount; i++) {
            let item = {
              key: i,
              title: i.toString(),
              class: [
                this.prefixCls + '-item',
                {
                  [`${this.prefixCls}-item-active`]: this.currentPage === i
                }
              ],
              num: i
            }
            array.push(item)
          }
        } else {
          const offset = Math.floor(PagerCount / 2) - 1
          for (let i = currentPage - offset; i <= currentPage + offset; i++) {
            let item = {
              key: i,
              title: i.toString(),
              class: [
                this.prefixCls + '-item',
                {
                  [`${this.prefixCls}-item-active`]: this.currentPage === i
                }
              ],
              num: i
            }
            array.push(item)
          }
        }
      } else {
        for (let i = 2; i < pageNum; i++) {
          let item = {
            key: i,
            title: i.toString(),
            class: [
              this.prefixCls + '-item',
              {
                [`${this.prefixCls}-item-active`]: this.currentPage === i
              }
            ],
            num: i
          }
          array.push(item)
        }
      }

      this.showPrewMore = showPrewMore
      this.showNextMore = showNextMore
      return array
    },
    maxPages () {
      // 计算最大的页码
      const maxPages = Math.ceil(this.total / this.currentPageSize)
      return maxPages === 0 ? 1 : maxPages
    },
    pagerClass (pager) {
      // 计算当前的展示
      // console.log(pager)
    },
    firstClass () {
      return [
        `${this.prefixCls}-item`,
        {
          [`${this.prefixCls}-item-active`]: this.currentPage === 1
        }
      ]
    },
    lastClass () {
      return [
        `${this.prefixCls}-item`,
        {
          [`${this.prefixCls}-item-active`]: this.currentPage === this.maxPages
        }
      ]
    },
    prevStandTextClass () {
      return [
        `${this.prefixCls}-prev-text`,
        {
          [`${this.prefixCls}-text-disable`]: this.currentPage === 1
        }
      ]
    },
    nextStandTextClass () {
      return [
        `${this.prefixCls}-next-text`,
        {
          [`${this.prefixCls}-text-disable`]: this.currentPage === this.maxPages
        }
      ]
    },
    prevClass () {
      return [
        `${this.prefixCls}-prev`,
        {
          [`${this.prefixCls}-disabled`]: this.currentPage === 1,
          [`${this.prefixCls}-custom-text`]: this.prevText !== ''
        }
      ]
    },
    nextClass () {
      return [
        `${this.prefixCls}-next`,
        {
          [`${this.prefixCls}-disabled`]: this.currentPage === this.maxPages,
          [`${this.prefixCls}-custom-text`]: this.prevText !== ''
        }
      ]
    },
    sizeClass () {
      return [`${this.prefixCls}-options-sizer`]
    },
    optionClass () {
      return [`${this.prefixCls}-options`]
    },
    selectClass () {
      return [`${this.prefixCls}-options-select`]
    },
    inputClass () {
      return [`${this.prefixCls}-options-elevator`]
    },
    showBtuType () {
      let type = 'primary'
      if (!this.showInputValue) {
        type = 'info'
      }
      return type
    }
  },
  watch: {
    total (val) {
      let maxPage = Math.ceil(val / this.currentPageSize)
      if (maxPage < this.currentPage) {
        this.currentPage = maxPage === 0 ? 1 : maxPage
      }
    },
    current (val) {
      this.currentPage = val
    },
    pageSize (val) {
      this.currentPageSize = val
    }
  },
  methods: {
    changeSize (pageSize) {
      this.$emit('on-page-size-change', pageSize)
      this.currentPage = 1
      this.cleanInputPageNum()
    },
    cleanInputPageNum () {
      this.showInputValue = ''
    },
    handlePageChange (page) {
      this.cleanInputPageNum()
      this.changePage(page)
    },
    changePage (page) {
      // 最近的修改
      if (this.currentPage !== page) {
        this.currentPage = page
        this.$emit('current-change', this.currentPage)
      }
    },
    fastPrev () {
      const page = this.currentPage - 5
      this.cleanInputPageNum()
      if (page > 0) {
        this.changePage(page)
      } else {
        this.changePage(1)
      }
    },
    fastNext () {
      const page = this.currentPage + 5
      this.cleanInputPageNum()
      if (page > this.maxPages) {
        this.changePage(this.maxPages)
      } else {
        this.changePage(page)
      }
    },
    prev () {
      this.showInputValue = ''
      const current = this.currentPage
      this.cleanInputPageNum()
      if (current <= 1) return false
      this.changePage(current - 1)
    },
    next () {
      this.showInputValue = ''
      const current = this.currentPage
      this.cleanInputPageNum()
      if (current >= this.maxPages) {
        return false
      }
      this.changePage(current + 1)
    },
    keyDown (e) {},
    keyUp (e) {},
    okBtuChangePage () {
      let val = this.showInputValue
      let page = 0
      if (Number(val) > this.maxPages) {
        this.showInputValue = this.maxPages
      }
      if (isValueNumber(val)) {
        val = Number(val)
        if (val !== this.currentPage) {
          const maxPage = this.maxPages
          if (val > maxPage) {
            page = maxPage
          } else {
            page = val
          }
        }
      } else {
        if (this.showInputValue) {
          page = 1
        } else {
          page = 0
        }
      }
      if (page) {
        this.changePage(page)
      }
    },
    keyUpChangePage (event) {
      let val = event.target.value.trim()
      let page = 0
      if (isValueNumber(val)) {
        if (Number(val) > this.maxPages) {
          this.showInputValue = this.maxPages
        }
        val = Number(val)
        if (val !== this.currentPage) {
          const maxPage = this.maxPages
          if (val > maxPage) {
            page = maxPage
          } else {
            page = val
          }
        }
      } else {
        page = 1
      }
      if (page) {
        event.target.value = page
        this.changePage(page)
      }
    },
    pageInputChange (event) {
      let val = event.target.value.trim()
      let page = 0
      if (!event.data || event.data.length > 0) {
        this.showInputValue = val
        return
      }
      if (isPositiveInteger(event.data)) {
        val = Number(val)
        if (val !== this.currentPage) {
          page = val
        }
      } else {
        page = 1
      }

      if (page) {
        this.showInputValue = page
      }
    }
  },
  created () {
    if (this.sizes !== 'large') {
      this.showText = false
      this.prefixCls = this.prefixCls + '-small'
    }
  }
}
</script>
